<?php
namespace app\common\model\food;

use app\common\model\BaseModel;
use think\facade\Db;

/**
 * 商品模型
 */
class Goods extends BaseModel
{
    // 定义表名
    protected $name = 'food_goods';

    // 定义主键
    protected $pk = 'goods_id';

    protected $append = ['goods_sales','stock'];

    /**
     * 商品库存
     */
    public function getStockAttr($value, $data)
    {
    
        $list = (new GoodsSpec)->where('goods_id',$data['goods_id'])->select();

        $value = 0;
        for($n=0;$n<sizeof($list);$n++){
            if($n==0){
                $value = $list[$n]['stock_num'];
            }else{
                $value = $value + $list[$n]['stock_num'];
            }
        }
        return $value;
    }

    /**
     * 计算显示销量 (初始销量 + 实际销量)
     */
    public function getGoodsSalesAttr($value, $data)
    {
        return $data['sales_initial'] + $data['sales_actual'];
    }

    /**
     * 关联商品分类表
     */
    public function category()
    {
        return $this->belongsTo('app\\common\\model\\food\\Category','category_id');
    }

    /**
     * 关联商品规格表
     */
    public function spec()
    {
        return $this->hasMany('app\\common\\model\\food\\GoodsSpec','goods_id')->order(['goods_spec_id' => 'asc']);
    }

    /**
     * 关联商品规格关系表
     */
    public function specRel()
    {
        return $this->belongsToMany('app\\common\\model\\food\\SpecValue', 'app\\common\\model\\food\\GoodsSpecRel','spec_value_id','goods_id');
    }

    /**
     * 关联商品图片表
     */
    public function image()
    {
        return $this->hasMany('app\\common\\model\\food\\GoodsImage','goods_id')->order(['id' => 'asc']);
    }

    /**
     * 显示状态
     */
    public function getGoodsStatusAttr($value)
    {
        $status = [10 => '上架', 20 => '下架'];
        return ['text' => $status[$value], 'value' => $value];
    }

    /**
     * 是否推荐
     */
    public function getIsRecommendAttr($value)
    {
        $status = ['否', '是'];
        return ['text' => $status[$value], 'value' => $value];
    }

    /**
     * 获取商品列表
     */
    public function getList($shop_id = 0,$status = 0, $category_id = 0, string $search = '', $sortType = 'all', $sortPrice = false)
    {
        // 筛选条件
        $filter = [];
        $shop_id > 0 && $filter['shop_id'] = $shop_id;
        $status > 0 && $filter['goods_status'] = $status;
        $category_id > 0 && $filter['category_id'] = $category_id;
        !empty($search) && $filter['goods_name'] = ['like', '%' . trim($search) . '%'];

        // 排序规则
        $sort = [];
        if ($sortType === 'all') {
            $sort = ['goods_sort', 'goods_id' => 'desc'];
        } elseif ($sortType === 'sales') {
            $sort = ['goods_sales' => 'desc'];
        } elseif ($sortType === 'price') {
            $sort = $sortPrice ? ['goods_max_price' => 'desc'] : ['goods_min_price'];
        }
        // 商品表名称
        $tableName = $this->getTable();
        // 多规格商品 最高价与最低价
        $GoodsSpec = new GoodsSpec;
        $minPriceSql = $GoodsSpec->field(['MIN(goods_price)'])
            ->where('goods_id', 'EXP', "= `$tableName`.`goods_id`")->buildSql();
        $maxPriceSql = $GoodsSpec->field(['MAX(goods_price)'])
            ->where('goods_id', 'EXP', "= `$tableName`.`goods_id`")->buildSql();
        // 执行查询
        $list = $this->field(['*', '(sales_initial + sales_actual) as goods_sales',
            "$minPriceSql AS goods_min_price",
            "$maxPriceSql AS goods_max_price"
        ])->with(['category', 'image.file', 'spec', 'spec.image'])
            ->where('is_delete', '=', 0)
            ->where($filter)
            ->order($sort)
            ->paginate(['list_rows'=>15,'query' => request()->param()]);
        return $list;
    }

    /**
     * 获取商品详情
     */
    public static function detail($id)
    {
        return self::with(['category', 'image.file', 'spec', 'spec.image', 'spec_rel.spec'])->find($id);
    }

    /**
     * 清除商品记录
     */
    public function remove($goods_id)
    {
        $filter['goods_id'] = $goods_id;
        // 开启事务
        Db::startTrans();
        try {
            $this->where($filter)->delete();
            GoodsImage::where($filter)->delete();
            GoodsSpec::where($filter)->delete();
            GoodsSpecRel::where($filter)->delete();
            Db::commit();
            return true;
        } catch (\Exception $e) {
            Db::rollback();
        }
        return false;
    }

    /**
     * 设置商品上下架
     */
    public function status()
    {
        $this->goods_status['value'] == 10 ? $this->goods_status = 20 :$this->goods_status = 10;
        return $this->save() !== false;
    }

    /**
     * 更新商品库存销量
     */
    public function updateStockSales($goodsList,$stock = false)
    {
        // 整理批量更新商品销量
        $goodsSave = [];
        // 批量更新商品规格：sku销量、库存
        $goodsSpecSave = [];
        foreach ($goodsList as $goods) {
            //增加销量
            $model = (new Goods)->get($goods['goods_id']);
            $model->sales_actual = ['inc', $goods['total_num']];
            $model->save();
            $model = (new GoodsSpec)->get($goods['goods_spec_id']);
            $model->goods_sales = ['inc', $goods['total_num']];
            // 付款减库存
            if ($stock) {
                $model->stock_num = ['dec', $goods['total_num']];
            }
            $model->save();
        }
    }























    /**
     * 获取商品列表 - DIY组件
     */
    public static function getAll($shop_id = 0,$sortType = 'all',$limit=null)
    {
        // 筛选条件
        $filter = [];
        $filter['goods_status'] = 10;
        $shop_id > 0 && $filter['shop_id'] = $shop_id;
        if($sortType == 'recommend'){
            $filter['is_recommend'] = 1;//推荐商品
        }
        // 排序规则
        $sort = [];
        if ($sortType === 'all') {
            $sort = ['sales_actual', 'goods_id' => 'desc'];
        } elseif ($sortType === 'sales') {
            $sort = ['goods_sales' => 'desc'];
        } elseif ($sortType === 'new') {
            $sort = ['goods_id' => 'desc'];
        }

        // 执行查询
        return self::with(['category', 'image.file', 'spec', 'spec.image'])
            ->where('is_delete', '=', 0)
            ->where($filter)
            ->order($sort)
            ->limit($limit)
            ->select();
    }

    /**
     * 猜您喜欢
     */
    public function getBestList($shop_id = 0,$limit=10)
    {
        // 筛选条件
        $filter = [];
        $filter['goods_status'] = 10;
        $filter['is_delete'] = 0;
        $shop_id > 0 && $filter['shop_id'] = $shop_id;
        return $this->with(['spec', 'category', 'image.file'])
            ->where($filter)
            ->order(['sales_initial' => 'desc', 'goods_sort' => 'asc'])
            ->limit($limit)
            ->select();
    }

    /**
     * 商品多规格信息
     */
    public function getGoodsSku(string $goods_sku_id = '')
    {
        $goodsSkuData = array_column($this['spec']->toArray(), null, 'spec_sku_id');
        if (!isset($goodsSkuData[$goods_sku_id])) {
            return false;
        }
        $goods_sku = $goodsSkuData[$goods_sku_id];
        // 多规格文字内容
        $goods_sku['goods_attr'] = '';
        if ($this['spec_type'] == 20) {
            $attrs = explode('_', $goods_sku['spec_sku_id']);
            $spec_rel = array_column($this['spec_rel']->toArray(), null, 'spec_value_id');
            foreach ($attrs as $specValueId) {
                if(!empty($goods_sku['goods_attr'])){
                    $goods_sku['goods_attr'] .= '/';
                }
                /*$goods_sku['goods_attr'] .= $spec_rel[$specValueId]['spec']['spec_name'] . ':'
                    . $spec_rel[$specValueId]['spec_value'];*/
                $goods_sku['goods_attr'] .= $spec_rel[$specValueId]['spec_value'];
            }
        }
        return $goods_sku;
    }
    
    /**
     * 获取规格信息
     */
    public function getManySpecData($spec_rel, $spec)
    {
        // spec_attr
        $specAttrData = [];
        foreach ($spec_rel as $item) {
            if (!isset($specAttrData[$item['spec_id']])) {
                $specAttrData[$item['spec_id']] = [
                    'group_id' => $item['spec']['spec_id'],
                    'group_name' => $item['spec']['spec_name'],
                    'spec_items' => [],
                ];
            }
            $specAttrData[$item['spec_id']]['spec_items'][] = [
                'item_id' => $item['spec_value_id'],
                'spec_value' => $item['spec_value'],
            ];
        }
    
        // spec_list
        $specListData = [];
        foreach ($spec as $item) {
            $image = (isset($item['image']) && !empty($item['image'])) ? $item['image'] : ['file_id' => 0, 'url' => ''];
            $spec_name = '';
            $spec_id_list = explode('_',$item['spec_sku_id']);
            for($n=0;$n<sizeof($spec_id_list);$n++) {
                foreach ($spec_rel as $vo) {
                    if($spec_id_list[$n] == $vo['spec_value_id']){
                        $spec_name .= $vo['spec_value'];
                        if($n+1 != sizeof($spec_id_list)){
                            $spec_name .= '/';
                        }
                    }
                }
            }
            $specListData[] = [
                'goods_spec_id' => $item['goods_spec_id'],
                'spec_sku_id' => $item['spec_sku_id'],
                'spec_name' => $spec_name,
                'rows' => [],
                'form' => [
                    'image_id' => $image['file_id'],
                    'image_url' => $image['url'],
                    'goods_no' => $item['goods_no'],
                    'goods_price' => $item['goods_price'],
                    'line_price' => $item['line_price'],
                    'stock_num' => $item['stock_num'],
                    'goods_weight' => $item['goods_weight']
                ],
            ];
        }
        return ['spec_attr' => array_values($specAttrData), 'spec_list' => $specListData];
    }
    
    /**
     * 获取商品总数
     */
    public static function getCount($shop_id=0)
    {
         // 筛选条件
        $filter = [];
        $shop_id > 0 && $filter['shop_id'] = $shop_id;
        $applet_id = self::$applet_id;
        $applet_id > 0 && $filter['applet_id'] = $applet_id;
        return self::withoutGlobalScope()->where($filter)->count();
    }
}
